#!/usr/bin/awk -f
# $Id: pf2pix.awk 9ce65bed8ef4 2012/08/26 02:14:51 pgurumur $
# Copyright (c) 2012 Prabhu Gurumurthy <pgurumur@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

# __version__  = "$Revision: 9ce65bed8ef4 $"
# __author__   = "$Author: pgurumur $"
# __modified__ = "$Date: 2012-08-26 02:14:51Z $"

BEGIN {
   if (ARGC <= 1) {
      printf("usage: pf2pix.awk filename\n");
      exit(1);
   }
}

function print_proto(iface, proto, source, dest, port) {
   src = "";
   if (source ~ /\<[0-9a-zA-z_]+\>/) {
      gsub(/\<|\>/, "", source);
      src = sprintf("%s %s", "object-group", source);
   }
   else if (source ~ /\$[0-9a-zA-Z_]+/) {
      gsub(/\$/, "", source);
      src = sprintf("%s %s", "host", source);
   }
   else {
      src = "any";
   }

   to = "";
   if (dest ~ /\<[0-9a-zA-z_]+\>/) {
      gsub(/\<|\>/, "", dest);
      to = sprintf("%s %s", "object-group", dest);
   }
   else if (dest ~ /\$[0-9a-zA-Z_]+/) {
      gsub(/\$/, "", dest);
      to = sprintf("%s %s", "host", dest);
   }
   else {
      to = "any";
   }

   if (iface == "$ext_if") {
      if (length(port)) {
         printf(\
            "access-list INTERNET_IN permit %s permit %s %s %s\n", \
            proto, src, to, port);
      }
      else {
         printf(\
            "access-list INTERNET_IN permit %s permit %s %s\n", proto, src, to);
      }
   }
   else if (iface == "$dmz_if") {
      if (length(port)) {
         printf(\
            "access-list DMZ_IN permit %s permit %s %s %s\n", \
            proto, src, to, port);
      }
      else {
         printf(\
            "access-list DMZ_IN permit %s permit %s %s\n", proto, src, to);
      }
   }
   else if (iface == "$int_if") {
      if (length(port)) {
         printf(\
            "access-list INTRANET_IN %s permit %s %s %s\n", \
            proto, src, to, port);
      }
      else {
         printf(\
            "access-list INTRANET_IN %s permit %s %s\n",proto, src, to);
      }
   }
}

(/^\#.*/ || /^$/) {
   next;
}

/[0-9]+\"$/ {
   sub(/\=/, " ");
   gsub(/\"/, " ");
   printf("name %s %s\n", $NF, $1);
}

$1 == "table" {
   while ($NF == "\\") {
	   sub(/\\$/, "");
		getline t;
		$0 = $0 t;
	}

   table = $2;
   gsub(/\<|\>/, "", table);
   printf("object-group network %s\n", table); 

#   gsub(/\\/, "");
   gsub(/\,/, " ");
   gsub(/[ \t]+/, " ");

   for (count = 5; count < NF; count++) {
      split($count, ip, /\//);
      split(ip[1], network, /\./);
      for (ix = 1; ix <= 4; ix++) {
         if (network[ix] == "") { 
            network[ix] = 0;
         }
      }

      addr = sprintf(\
           "%s.%s.%s.%s", network[1], network[2], network[3], network[4]);

      if (ip[2] == "22") {
         printf("network-object %s 255.255.252.0\n", addr);
      }
      else if (ip[2] == "24") {
         printf("network-object %s 255.255.255.0\n", addr); 
      }
      else if (ip[2] == "26") {
         printf("network-object %s 255.255.255.192\n", addr);
      }
      else if (ip[2] == "28") {
         printf("network-object %s 255.255.255.240\n", addr);
      }
      else if (ip[2] == "29") {
         printf("network-object %s 255.255.255.248\n", addr);
      }
      else if (ip[2] == "30") {
         printf("network-object %s 255.255.255.252\n", addr);
      }
      else {
         printf("network-object host %s\n", addr);
      }
   }

   printf("exit\n\n");
}

/^.*_ports =/ {
   gsub(/\,/, " ");
   printf("object-group service %s tcp\n", toupper($1));
   for (ix = 4; ix < NF; ix++) {
      split($ix, range, /\:/)
      if (range[2] != "") {
         printf("port-object range %s %s\n", range[1], range[2]);
      }
      else {
         printf("port-object eq %s\n", $ix);
      }
   }

   printf("exit\n\n");
}

/^nat\ on/ {
	src = "";
	if ($8 == "<INTRANET>") {
		src = "10.200.0.0 255.255.252.0";
	}
	else if ($8 == "<S175DATA>") {
		src = "10.208.0.0 255.255.252.0";
	}

	printf("nat (inside) 1 %s\n", src);
}

/^pass\ in/ && /tcp|udp|icmp\ from/ {

   newline = "";
   if ($NF == "\\") {
      sub(/\\$/, " ");
	   getline t;
	   newline = $0 t;
	   $0 = newline
	}
	else {
	   newline = $0;
	}

	gsub(/\\/, "");
	gsub(/[ \t]+/, " ");
	newline = $0;

   ix = 0;
   if ($5 == "on") {
      interface = $6;
		if ($7 == "proto") {
			protocol = $8;
			source = $10;
         dest = $12;
			ix = 8;
		}
		else {
      	protocol = $9;
			source = $11 
         dest = $13;
      	ix = 9;
		}
   }
   else {
      interface = $5; 
      protocol = $8;
		source = $10; 
      dest = $12;
      ix = 8;
   }

   dest_port = "";
   if ($0 ~ /port\ =/) {
      dest_port = sprintf("%s %s", "eq", $(ix + 7));
   }
   else if ($0 ~ /port\ \{\ [0-9]+/) {
      ports = sprintf("%s %s", $(ix + 7), $(ix + 9));
      gsub(/\,/, "", ports);
      dest_port = sprintf("%s %s", "range", ports);
   }
   else if ($0 ~ /port/) {
      gsub(/\$/, "", $(ix + 6)); 
      dest_port = sprintf("%s %s", "object-group", toupper($(ix + 6)));
   }

	if (interface == "$int_if") {
		source = "any";
      dest = "any";
	}

   if (protocol != "{") {
      print_proto(interface, protocol, source, dest, dest_port);
   }
   else {
		if (interface != "$int_if") {
			source = $13;
         dest = $15;
		}

      proto_list = $(ix + 1) $(ix + 2);
      split(proto_list, pl, /\,/);
         
      for (p in pl) {
         print_proto(interface, pl[p], source, dest, dest_port);
      }
   }
}
